﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;

namespace TinyAsset.Editor
{
    public class Builder
    {
        public const string kStrApp = "App";
        public const string kStrRes = "Res";

        const string kStrMenuBuildAssets = "TinyAsset/Build Assets";
        const string kStrMenuBuildPlayer = "TinyAsset/Build Player";
        const string kStrMenuUseAssetDatabase = "TinyAsset/Use AssetDatabase";
        const string kStrMenuAnalyzeAssets = "TinyAsset/Analyze Assets";

        const string kStrBuildSettingPath = "Assets/BuildConfig/BuildSetting.asset";

        [MenuItem(kStrMenuBuildAssets)]
        static void BuildAssets()
        {
            BuildProject(false);
        }

        [MenuItem(kStrMenuBuildPlayer)]
        static void BuildPlayer()
        {
            BuildProject(true);
        }

        static void BuildProject(bool isBuildPlayer)
        {
            BuildSetting buildSetting = AssetDatabase.LoadAssetAtPath<BuildSetting>(kStrBuildSettingPath);

            BuildContext context = new BuildContext();
            context.buildSetting = buildSetting;
            context.buildSetting.isBuildPlayer = isBuildPlayer;

            context.AppVersion = null;
            context.ResVersion = null;

            BuildPipeline pipeline = new BuildPipeline(context);
            pipeline.Append(new BuildPrepareTask());
            pipeline.Append(new BuildCollectTask());
            pipeline.Append(new BuildAnalyzeTask());
            pipeline.Append(new BuildPlayerTask());
            pipeline.Run();
        }

        [MenuItem(kStrMenuAnalyzeAssets)]
        static void AnalyzeAssets()
        {
            var buildSetting = AssetDatabase.LoadAssetAtPath<BuildSetting>(kStrBuildSettingPath);

            BuildContext context = new BuildContext();
            context.buildSetting = buildSetting;

            BuildPipeline pipeline = new BuildPipeline(context);
            pipeline.Append(new BuildCollectTask());
            pipeline.Append(new BuildAnalyzeTask());
            pipeline.Run();
        }

        public static Manifest CreateAssetDatabaseProfile()
        {
            var buildSetting = AssetDatabase.LoadAssetAtPath<BuildSetting>(kStrBuildSettingPath);

            BuildContext context = new BuildContext();
            context.buildSetting = buildSetting;

            BuildPipeline pipeline = new BuildPipeline(context);
            pipeline.Append(new BuildCollectTask());
            pipeline.Append(new BuildAnalyzeTask());
            pipeline.Run();

            Manifest manifest = new Manifest();

            List<BundledAssetKey> bundledAssets = new List<BundledAssetKey>();
            List<string> dirs = new List<string>();

            foreach (var item in context.assetBundles.Values)
            {
                foreach (var assetName in item.Assets)
                {
                    string path = assetName.Substring(7);
                    string dir = path.Substring(0, path.LastIndexOf('/') + 1);
                    string name = path.Substring(path.LastIndexOf('/') + 1);

                    if (!dirs.Contains(dir))
                        dirs.Add(dir);

                    bundledAssets.Add(new BundledAssetKey()
                    {
                        name = name,
                        bundle = -1,
                        dir = dirs.FindIndex(s => s == dir)
                    });
                }
            }

            manifest.bundledAssetKeys = bundledAssets.ToArray();
            manifest.dirs = dirs.ToArray();

            return manifest;
        }

        [MenuItem(kStrMenuUseAssetDatabase)]
        static void UseAssetDatabase()
        {
            if (Application.isPlaying)
                return;
            AssetBundleUtility.kUseAssetDatabase = !AssetBundleUtility.kUseAssetDatabase;
        }

        [MenuItem(kStrMenuUseAssetDatabase, true)]
        static bool UseAssetDatabaseValidate()
        {
            Menu.SetChecked(kStrMenuUseAssetDatabase, AssetBundleUtility.kUseAssetDatabase);
            return true;
        }
    }
}